// 分组码
#include <iostream>
#include <math.h>
#include <iomanip>
#include <stdlib.h>
using namespace std;

#define MAX 10 /*矩阵最大行数和列数*/

int str2int(const char *str)
{
    int temp = 0;
    const char *ptr = str;          //ptr保存str字符串开头
    if (*str == '-' || *str == '+') //如果第一个字符是正负号则移到下一个字符
    {
        str++;
    }
    while (*str != 0)
    {
        if ((*str < '0') || (*str > '9')) //如果当前字符不是数字则退出循环
        {
            break;
        }
        temp = temp * 10 + (*str - '0'); //如果当前字符是数字则计算数值
        str++;                           //移到下一个字符
    }
    if (*ptr == '-') //如果字符串是以“-”开头，则转换成其相反数
    {
        temp = -temp;
    }
    return temp;
}

int main()
{
    int Cmg[MAX][MAX] = {0};
    int C[MAX][MAX] = {0};
    int H[MAX][MAX] = {0};
    int d_min[8] = {0};
    int i, j, k;
    int num;
    int len;
    int sum = 0;
    char s[20];
    int M[8][3];
    int G[3][6] = {{1, 0, 0, 1, 1, 0},
                   {0, 1, 0, 1, 0, 1},
                   {0, 0, 1, 0, 1, 1}};
    cout << "generator matrix:   " << endl;
    cout << "G = " << endl;
    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 6; j++)
            cout << "  " << G[i][j];
        cout << endl;
    }
    cout << endl;
    cout << "information matrix:   " << endl;
    cout << "M = " << endl;
    for (int i = 0; i < 8; i++)
    {
        itoa(i, s, 2);
        len = strlen(s);
        num = str2int(s); //把字符串转换成整型数
        if (len == 1)
        {
            M[i][2] = num;
            M[i][1] = 0;
            M[i][0] = 0;
        }
        if (len == 2)
        {
            M[i][2] = num % 10;
            M[i][1] = num / 10;
            M[i][0] = 0;
        }
        if (len == 3)
        {
            M[i][2] = num % 10;      //取个位数字
            M[i][1] = num / 10 % 10; //取十位在数字
            M[i][0] = num / 100;     //取百位数字
        }
    }
    for (int i = 0; i < 8; i++) //二维数组输出形式
    {
        for (int j = 0; j < 3; j++)
            cout << " " << M[i][j];
        cout << endl;
    }

    //矩阵相乘得到新矩阵
    for (i = 0; i < 8; i++)
        for (j = 0; j < 6; j++)
            for (k = 0; k < 3; k++)
            {
                Cmg[i][j] += M[i][k] * G[k][j];
            }
    //对相乘得到的矩阵中每个元素取模2
    for (i = 0; i < 8; i++)
        for (j = 0; j < 6; j++)
        {
            C[i][j] = Cmg[i][j] % 2;
        }
    //输出编码矩阵
    cout << endl;
    cout << "code matrix:   " << endl;
    cout << "C = " << endl;

    for (i = 0; i < 8; i++)
    {
        for (j = 0; j < 6; j++)
            cout << "  " << C[i][j];
        cout << endl;
    }
    cout << endl;
    //计算最小码距d_min
    cout << "The weight of every codeword:	";
    for (i = 0; i < 8; i++) //计算每行码字
    {
        for (j = 0; j < 6; j++)
        {
            sum += C[i][j];
            d_min[i] = sum;
        }
        sum = 0;
        cout << "  " << d_min[i];
    }
    int min;
    for (i = 0; i < 7; i++) // 求出最小码距
    {
        if (d_min[i] < d_min[i + 1] && d_min[i] != 0 && d_min[i + 1] != 0)
            min = d_min[i];
        else
            min = d_min[i + 1];
    }
    cout << endl
         << endl;
    cout << "the minimum distance:   " << endl
         << endl;
    cout << "d_min =  " << min;
    cout << endl
         << endl;
    //求校验矩阵
    cout << "parity-check matrix:   " << endl;
    cout << "H = " << endl;
    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 6; j++)
        {
            H[i][j] = G[2 - i][5 - j];
            cout << "  " << H[i][j];
        }
        cout << endl;
    }
    cout << endl
         << endl
         << endl
         << endl
         << endl
         << endl;
    return 0;
}
